package com.sophialex.health.record.common.showKtable;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Composite;

import com.sophialex.health.record.common.util.PublicConstants;
import com.sophialex.health.record.common.util.StoreUtil;
import com.sophialex.health.system.frame.print.ReportPtnBean;
import com.sophialex.health.system.lktable.LKTable;

import de.kupzog.ktable.KTable;
import de.kupzog.ktable.KTableSortComparator;
import de.kupzog.ktable.KTableSortOnClick;
import de.kupzog.ktable.SWTX;
import de.kupzog.ktable.editors.KTableCellEditBase;

/**
 * 
 *  将KTable和ShowKTableModel的功能封装起来，使用起来更加方便
 * 
 */
public class ShowKTable extends KTable {
	public final static int L = SWTX.ALIGN_HORIZONTAL_LEFT;
	public final static int R = SWTX.ALIGN_HORIZONTAL_RIGHT;
	public final static int C = SWTX.ALIGN_HORIZONTAL_CENTER;

	private boolean addCountCol = true;// 是否加入第一列为行数的列

	// KTable对应的Model
	private ShowKTableModel model;
	private LKTable lkTable;
	private List<Object> data = null;// 与Model中的数据一致

	// 这个类里面保存与用户设置一致值，在对应的set方法中处理与Model中的差异
	private int fixColumnCount = 1;// 默认固定一列,必须 >= 1
	private int fixRowCount = 1;// 固定行，必须 >=1,表头一定为固定列
	private int[] columnAligns;
	private int[] columnWidths;

	// 与Model中的一致
	private String[] columnTitles;
	private String[] columnProperties;

	private int columnCount = 1; // 包括固定列
	private String key;
	private int[] ncolumn = null;
	private boolean editable = false;
	private int[] colorColumn = null;

	private String[] columnTitles_all; // 全表列名称
	private String[] columnProperties_all; // 全表列属性
	private int[] columnWidths_all; // 全表列宽度

	public String[] getColumnTitles_all() {
		return columnTitles_all;
	}

	public String[] getColumnProperties_all() {
		return columnProperties_all;
	}

	public int[] getColumnWidths_all() {
		return columnWidths_all;
	}

	public int[] getColumnAligns_all() {
		return columnAligns_all;
	}

	private int[] columnAligns_all; // 全表列样式
	private Color columnColor;
	private KTableCellEditBase kTableCellEditBase = new KTableCellEditBase();
	protected int style;
	private KTableSortOnClick tableSort = new KTableSortOnClick(this,
			new ShowKTableSortComparator(this.getModel(), -1,
					KTableSortComparator.SORT_NONE));

	/**
	 * 构造函数,一般要使用 FULL_SELECTION 样式,否则那些选中一行的方法无效
	 * 
	 * @param parent
	 * @param style
	 */
	public ShowKTable(Composite parent, String key, boolean addCountCol,
			int style) {
		super(parent, style);
		this.key = key;
		this.style = style;
		fixColumnCount = 1;
		fixRowCount = 1;
		this.addCountCol = addCountCol;
		init(null, null);
		addDisposeListener();
	}

	/**
	 * 构造函数 请使用 FULL_SELECTION 样式
	 * 
	 * @param parent
	 * @param style
	 * @param columnTitles
	 *            表头
	 * @param columnProperties
	 * 
	 */
	public ShowKTable(Composite parent, String key, boolean addCountCol,
			int style, String[] columnTitles, String[] columnProperties) {
		super(parent, style);
		this.style = style;
		this.addCountCol = addCountCol;
		this.key = key;
		// 在所有列前面加上默认的序号列，自动计算并设置默认的 columnWidths 和 columnAligns
		fixColumnCount = 1;
		fixRowCount = 1;
		init(columnTitles, columnProperties);
		addDisposeListener();
	}

	private void addDisposeListener() {
		this.addDisposeListener(new DisposeListener() {
			public void widgetDisposed(DisposeEvent arg0) {
				// saveStore();
				StoreUtil.save(StoreUtil.COLUMN_WIDTH + key, model
						.getColumnWidth());
			}
		});
	}

	public void saveStore() {
		model.saveStore();
	}

	/*
	 * 带Checkbox的构造函数
	 */
	public ShowKTable(Composite parent, String key, boolean addCountCol,
			int style, String[] columnTitles, String[] columnProperties,
			String checkBoxProperty) {
		super(parent, style);
		this.style = style;
		this.addCountCol = addCountCol;
		this.key = key;
		// 在所有列前面加上默认的序号列，自动计算并设置默认的 columnWidths 和 columnAligns
		init(columnTitles, columnProperties, checkBoxProperty);
		fixColumnCount = 2;
		fixRowCount = 1;
		addDisposeListener();
	}

	/**
	 * 通过Key值来获取本地存储的表头名称集合
	 */
	protected String[] getXsColumnTitles() {
		String str = StoreUtil.store.getString(StoreUtil.COLUMN_TITLE + key);
		if (str != null && !"".equals(str)) {
			return str.split(StoreUtil.SEPARTER);
		} else {
			return null;
		}
	}

	/**
	 * 通过Key值来获取本地存储的列属性集合
	 */
	protected String[] getXsColumnProperties() {
		String str = StoreUtil.store
				.getString(StoreUtil.COLUMN_PROPERTIE + key);
		if (str != null && !"".equals(str)) {
			return str.split(StoreUtil.SEPARTER);
		} else {
			return null;
		}
	}

	/**
	 * 通过Key值来获取本地存储的列样式集合
	 */
	protected String[] getXsColumnAligns() {
		String str = StoreUtil.store.getString(StoreUtil.COLUMN_STYLE + key);
		if (str != null && !"".equals(str)) {
			return str.split(StoreUtil.SEPARTER);
		} else {
			return null;
		}
	}

	/**
	 * 通过Key值来获取本地存储的列宽度集合
	 */
	protected String[] getXsColumnWidths() {
		String str = StoreUtil.store.getString(StoreUtil.COLUMN_WIDTH + key);
		if (str != null && !"".equals(str)) {
			return str.split(StoreUtil.SEPARTER);
		} else {
			return null;
		}
	}

	/*
	 * 初始化类
	 */
	private void init(String[] columnTitles, String[] columnProperties) {
		setTitlesAndProperties(columnTitles, columnProperties);
	}

	/*
	 * 带Checkbox的初始化
	 */
	private void init(String[] columnTitles, String[] columnProperties,
			String checkboxProperty) {
		setColumnTitles(columnTitles);
		setColumnProperties(columnProperties);
		model = new ShowKTableModel(data, key, addCountCol, getColumnTitles(),
				getColumnProperties(), getColumnWidths(), getFixRowCount(),
				getFixColumnCount(), "yyyy-MM-dd HH:mm", true, checkboxProperty);
		this.setColumnAligns(this.columnAligns);
		this.setModel(model);
		if (tableSort != null) {
			this.removeCellSelectionListener(tableSort);
		}
		tableSort = new KTableSortOnClick(this, new ShowKTableSortComparator(
				model, -1, KTableSortComparator.SORT_NONE));
		this.addCellSelectionListener(tableSort);
	}

	/**
	 * 设置可编辑列及是否可编辑
	 * 
	 * @param ncolumn
	 * @param editable
	 */
	public void setEditColumn(int[] ncolumn, boolean editable) {

		this.ncolumn = ncolumn;
		this.editable = editable;
	}

	/**
	 * 设置整列颜色
	 * 
	 * @param colorColumn
	 * @param columnColor
	 */
	public void setColorColumn(int[] colorColumn, Color columnColor) {
		this.colorColumn = colorColumn;
		this.columnColor = columnColor;
	}

	/**
	 * 设置列信息，包括表头和数据字段
	 * 
	 * @param columnTitles
	 * @param columnProperties
	 */
	public void setTitlesAndProperties(String[] columnTitles,
			String[] columnProperties) {
		if (columnProperties_all == null) {
			columnProperties_all = columnProperties;
			if (getXsColumnProperties() != null) {
				columnProperties = getXsColumnProperties();
			}
		}
		if (columnTitles_all == null) {
			columnTitles_all = columnTitles;
			if (getXsColumnTitles() != null) {
				columnTitles = getXsColumnTitles();
			}
		}
		setColumnTitles(columnTitles);
		setColumnProperties(columnProperties);
		model = new ShowKTableModel(data, key, addCountCol, getColumnTitles(),
				getColumnProperties(), getColumnWidths(), getFixRowCount(),
				getFixColumnCount(), "yyyy-MM-dd HH:mm", ncolumn, editable,
				colorColumn, columnColor, kTableCellEditBase);
		this.setColumnAligns(this.columnAligns);
		this.setModel(model);
		if (tableSort != null) {
			this.removeCellSelectionListener(tableSort);
		}
		tableSort = new KTableSortOnClick(this, new ShowKTableSortComparator(
				model, -1, KTableSortComparator.SORT_NONE));
		this.addCellSelectionListener(tableSort);

	}

	// 默认为1不可设置
	private int getFixRowCount() {
		return this.fixRowCount;
	}

	/**
	 * 设置表头，加上一个序号列
	 * 
	 * @param columnTitles
	 */
	private void setColumnTitles(String[] columnTitles) {
		if (addCountCol) {
			// 设置默认固定行固定列
			this.fixColumnCount = 1;
			this.fixRowCount = 1;

			if (columnTitles == null || columnTitles.length == 0) {
				columnAligns = new int[] { C };
				columnWidths = new int[] { 30 };
				// 序号列
				this.columnTitles = new String[] { "" };
				this.columnCount = 1;
				return;
			}

			int length = columnTitles.length;

			this.columnCount = length + 1;

			String[] modelColumnTitles = new String[length + 1];
			modelColumnTitles[0] = "";

			// 根据columnCount来创建默认的 alignment 和 width
			this.columnAligns = new int[this.columnCount];
			this.columnAligns[0] = C;
			this.columnWidths = new int[this.columnCount];
			this.columnWidths[0] = 30;

			for (int index = 0; index < length; index++) {
				modelColumnTitles[index + 1] = columnTitles[index];
				this.columnAligns[index + 1] = L;
				this.columnWidths[index + 1] = 100;
			}
			this.columnTitles = modelColumnTitles;
		} else {
			// 设置默认固定行固定列
			this.fixColumnCount = 1;
			this.fixRowCount = 1;

			if (columnTitles == null || columnTitles.length == 0) {
				return;
			}

			this.columnCount = columnTitles.length;

			// 根据columnCount来创建默认的 alignment 和 width
			this.columnAligns = new int[this.columnCount];
			this.columnWidths = new int[this.columnCount];

			for (int index = 0; index < columnCount; index++) {
				this.columnAligns[index] = L;
				this.columnWidths[index] = 100;
			}
			this.columnTitles = columnTitles;
		}

	}

	/**
	 * 取得表头
	 * 
	 * @return String[]
	 */
	private String[] getColumnTitles() {
		return this.columnTitles;
	}

	/**
	 * 设置表列属性,可设置嵌套属性，形如 fid.fbh
	 * 
	 * @param columnProperties
	 *            String[]
	 */
	private void setColumnProperties(String[] columnProperties) {
		if (addCountCol) {
			if (columnProperties == null || columnProperties.length == 0) {
				// 序号列
				this.columnProperties = new String[] { "" };
				return;
			}

			int length = columnProperties.length;
			String[] modelColumnProperties = new String[length + 1];
			modelColumnProperties[0] = "";

			for (int index = 0; index < length; index++) {
				modelColumnProperties[index + 1] = columnProperties[index];
			}
			this.columnProperties = modelColumnProperties;
		} else {
			this.columnProperties = columnProperties;
		}
	}

	/**
	 * 取得属性
	 * 
	 * @return String[] 属性数组
	 */
	private String[] getColumnProperties() {
		return this.columnProperties;
	}

	/**
	 * 设置表格要显示的数据
	 * 
	 * @param data
	 *            List<Object>
	 */
	public void setInput(List data) {
		// 设置 model
		this.data = data;
		if (model != null) {
			model.setData(data);
		}
		redraw();
	}

	/**
	 * 取得表格中显示的数据
	 * 
	 * @return data List<Object>
	 */
	public List getInput() {
		return this.data;
	}

	/**
	 * 刷新表格显示的数据
	 */
	public void refresh() {
		this.redraw();
	}

	/**
	 * 取得选中的行对应的数据列表
	 * 
	 * @return List<Object> 如果没有选中,返回 empty list
	 */
	public List<Object> getSelection() {
		List<Object> selectionObject = new ArrayList<Object>();
		if ((style & SWT.FULL_SELECTION) != 0) {
			int[] rowArray = this.getRowSelection();
			if (rowArray != null) {
				for (int index = 0; index < rowArray.length; index++) {
					selectionObject.add(model.getRow(rowArray[index]));
				}
			}
		} else {
			if (this.data != null && this.data.size() > 0) {
				if (m_FocusRow > 0) {
					selectionObject.add(data.get(m_FocusRow - 1));
				}
			}
		}
		return selectionObject;
	}

	/**
	 * 根据行获得对象
	 * 
	 * @param row
	 * @return
	 */
	public Object getSelectData(int row) {
		if (this.data != null && this.data.size() > 0) {
			if (row > 0 && row <= data.size()) {
				return data.get(row - 1);
			}
		}
		return null;
	}

	/**
	 * 取和选中的第一行
	 * 
	 * @return Object 选中行对应的对象，如果没有选中，返回 null
	 */
	public Object getFirstSelection() {
		List<Object> list = getSelection();
		if (!list.isEmpty()) {
			return list.get(0);
		}
		return null;
	}

	/**
	 * 设置固定列，
	 * 
	 * @param fixColumnCount
	 *            ,不包括序号列的设置，序号列固定
	 */
	public void setFixColumnCount(int fixColumnCount) {
		if (fixColumnCount < 1) {
			this.fixColumnCount = 0;
		} else {
			this.fixColumnCount = fixColumnCount + 1;
		}
		if (model != null) {
			model.setFixColumnCount(this.fixColumnCount);
		}
	}

	/**
	 * 取得固定列
	 * 
	 * @param int
	 */
	private int getFixColumnCount() {
		return this.fixColumnCount;
	}

	public void setSelection(Object pobj) {
		setSelection(pobj, true);
	}

	/**
	 * 根据对象的equal方法来选中一行
	 * 
	 * @param Object
	 *            obj
	 * 
	 */
	public void setSelection(Object pobj, boolean scroll) {
		// 要验证对象的类型
		if (pobj == null) {
			return;
		}
		int row = 0;
		int rowCount = model.getRowCount();
		while (row < rowCount) {
			Object obj = model.getRow(row);
			if (pobj.equals(obj)) {
				this.setSelection(this.fixColumnCount + 1, row, false);
			}
			row++;
		}
		if (scroll) {
			scrollToFocus();
		}
	}

	@Override
	public void setSelection(Point[] selections, boolean scroll) {
		checkWidget();
		if (selections == null || selections.length < 1) {
			clearSelection();
			return;

		} else if (isMultiSelectMode()) {
			try {
				this.setRedraw(false);
				for (int i = 0; i < selections.length; i++) {
					int col = selections[i].x;
					int row = selections[i].y;
					if (col < m_Model.getColumnCount()
							&& row < m_Model.getRowCount()
							&& row >= m_Model.getFixedHeaderRowCount())
						if (i == 0)
							focusCell(col, row, SWT.CTRL);
						else
							addToSelectionWithoutRedraw(col, row);
				}

				if (scroll)
					scrollToFocus();
			} finally {
				this.setRedraw(true);
			}
		} else {
			setSelection(selections[0].x, selections[0].y, scroll);
		}
	}

	/**
	 * 根据实体的属性名及对应的值来选中行，如果有多列符合条件， 将选中多列，并返回对象列表
	 * 
	 * @param fieldName
	 *            字段名
	 * @param value
	 *            String, 以字符串形式进行比较
	 * @return List<Object>
	 */
	// public List<Object> setSelection(String fieldName,String value){
	// //TODO
	// return null;
	// }

	/**
	 * 根据实体的属性名及对应的值来选中一行，如果有多列符合条件,选中第一行
	 * 
	 * @param fieldName
	 *            字段名 可以为嵌套字段
	 * @param value
	 *            String, 以字符串形式进行比较
	 */
	public void setFirstSelection(String fieldName, String value) {

		if (fieldName == null || fieldName.trim().equals("") || value == null) {
			return;
		}

		int row = 0;
		int rowCount = model.getRowCount();
		while (row < rowCount) {
			Object obj = model.getRow(row);
			Object fieldValue = getProperty(obj, fieldName);

			if (fieldValue != null
					&& fieldValue.toString().equalsIgnoreCase(value)) {
				this.setSelection(this.fixColumnCount + 1, row, false);
				return;
			}
			row++;
		}
	}

	/**
	 * 
	 * 读取嵌套属性的值
	 * 
	 * @param obj
	 * @param fieldName
	 * @return
	 */
	private Object getProperty(Object obj, String fieldName) {
		if (obj == null || fieldName == null) {
			return null;
		}
		Object tempObj = obj;
		Object value = null;
		String[] fieldList = fieldName.split("\\.");
		for (int index = 0; index < fieldList.length; index++) {
			if (tempObj == null) {
				break;
			}
			value = PublicConstants.getProperty(tempObj, fieldList[index]);
			tempObj = value;

		}
		return value;
	}

	/**
	 * 设置对应的列宽
	 * 
	 * @param pcolumnWidths
	 */
	public void setColumnWidths(int[] pcolumnWidths) {
		if (columnWidths_all == null) {
			columnWidths_all = pcolumnWidths;
		}
		setColumnWidths(pcolumnWidths, true);
	}

	/**
	 * 设置对应的列宽
	 * 
	 * @param pcolumnWidths
	 */
	public void setColumnWidths(int[] pcolumnWidths, boolean b) {
		if (getXsColumnWidths() != null && b) {
			pcolumnWidths = checkValue(columnWidths_all, columnProperties_all,
					getXsColumnWidths());
		}
		if (columnWidths_all == null) {
			columnWidths_all = pcolumnWidths;
		}
		if (addCountCol) {
			if (pcolumnWidths == null || pcolumnWidths.length == 0) {
				// 序号列
				// this.columnWidths = new int[]{30};
				if (model != null) {
					model.setColumnWidths(this.columnWidths);
				}
				return;
			}

			int length = pcolumnWidths.length;

			this.columnWidths = new int[length + 1];
			this.columnWidths[0] = 30;

			for (int index = 0; index < length; index++) {
				this.columnWidths[index + 1] = pcolumnWidths[index];
			}
			// 设置Model的属性
			if (model != null) {
				model.setColumnWidths(this.columnWidths);
			}
		} else {
			this.columnWidths = pcolumnWidths;
			model.setColumnWidths(this.columnWidths);
		}
	}

	/**
	 * 取得列宽
	 * 
	 * @return int[]
	 * 
	 */
	public int[] getColumnWidths() {
		return this.columnWidths;
	}

	/**
	 * 设置 columnAlignments
	 * 
	 * @param int[] 取本类中的 L(LEFT),C(CENTER),R(RIGHT)
	 */
	public void setColumnAligns(int[] pcolumnAligns) {
		if (columnAligns_all == null) {
			columnAligns_all = pcolumnAligns;
		}
		setColumnAligns(pcolumnAligns, true);
	}

	/**
	 * 设置 columnAlignments
	 * 
	 * @param int[] 取本类中的 L(LEFT),C(CENTER),R(RIGHT)
	 */
	public void setColumnAligns(int[] pcolumnAligns, boolean b) {
		if (getXsColumnAligns() != null && b) {
			int[] is = checkValue(columnAligns_all, columnProperties_all,
					getXsColumnAligns());
			if (is != null)
				pcolumnAligns = is;
		}
		if (columnAligns_all == null) {
			columnAligns_all = pcolumnAligns;
		}
		if (addCountCol) {
			if (pcolumnAligns == null || pcolumnAligns.length == 0) {
				// 序号列
				// this.columnAligns = new int[]{C};
				if (model != null) {
					model.setColumnAligns(this.columnAligns);
				}
				return;
			}

			int length = pcolumnAligns.length;

			this.columnAligns = new int[length + 1];
			this.columnAligns[0] = 30;

			for (int index = 0; index < length; index++) {
				this.columnAligns[index + 1] = pcolumnAligns[index];
			}
			// 设置Model的属性
			if (model != null) {
				model.setColumnAligns(this.columnAligns);
			}
		} else {
			this.columnAligns = pcolumnAligns;
			model.setColumnAligns(this.columnAligns);
		}
	}

	/**
	 * 取得 Table对应的 ShowKTableModel 用户可以使用Model中的功能，不受ShowKTable的限制
	 * 
	 * @param ShowKTableModel
	 */
	@Override
	public ShowKTableModel getModel() {
		// TODO Auto-generated method stub
		return model;
	}

	/**
	 * 打开样式设计器
	 * */
	public void openStyle() {
	}

	/**
	 * 行选中监听器
	 * 
	 * @param KTableRowSelectionListener
	 */
	public void addRowSelectionListener(KTableRowSelectionListener listener) {
		this.addCellSelectionListener(listener);
	}

	/**
	 * 选中行 从 1 开始
	 * 
	 * @param row
	 *            要选中的行号
	 */
	public void selectRow(int row) {
		if (row < 1) {
			return;
		}
		this.setSelection(fixColumnCount + 1, row, false);
	}

	public void setJoinOut(ISKJoinOutValue joinOut) {
		this.getModel().setJoinOut(joinOut);
	}

	public void setKTableCellEditBase(KTableCellEditBase kTableCellEditBase) {
		this.kTableCellEditBase = kTableCellEditBase;
	}

	public String[][] getPrintData() {
		return model.getPrintData();
	}

	public ReportPtnBean getPtnBean() {
		return model.getPtnBean();
	}

	public Map<String, String[]> getDoubleMap() {
		return model.getDoubleMap();
	}

	public void setDoubleMap(Map<String, String[]> doubleMap) {
		this.model.setDoubleMap(doubleMap);
	}

	/**
	 * 初始化DoubleMap
	 * 
	 * @param flsdj
	 *            零售单价对应的属性
	 * @param fpfdj
	 *            批发单价对应的属性
	 * @param fjhdj
	 *            进货单价对应的属性
	 * @param fje
	 *            金额对应的属性
	 */
	public void initDoubleMap(String[] flsdj, String[] fjhdj, String[] fpfdj,
			String[] fje) {
		this.model.initDoubleMap(flsdj, fjhdj, fpfdj, fje);
	}

	@Override
	protected void focusCell(int col, int row, int stateMask) {
		super.focusCell(col, row, stateMask);
		if (ncolumn != null && ncolumn.length > 0) {
			for (int i : ncolumn) {
				if (i == col) {
					openEditorInFocus();
				}
			}
		}
	}

	/**
	 * 检查 列的宽度 和 样式的 正确性
	 * 
	 * @param ints_all
	 *            所有的列宽 和列样式 集合
	 * @param strs_all
	 *            所有的列属性名
	 * @param ints
	 *            格式 abc_|_50_&_bbb_|_60 (列属性名+ 宽度 或者 列属性名+ 样式 )
	 * @return
	 */
	private int[] checkValue(int[] ints_all, String[] strs_all, String[] ints) {
		if (ints_all == null || strs_all == null) {
			return null;
		}
		boolean b = false;
		String str = "";
		String[] temps;
		for (int i = 0; i < ints.length; i++) {
			temps = ints[i].split(StoreUtil.SEPARTER_fen);
			for (int j = 0; j < strs_all.length; j++) {
				if (temps[0].equals(strs_all[j])) {
					b = true;
					break;
				}
			}
			if (b) {
				if ("".equals(str)) {
					str = temps[1];
				} else {
					str = str + StoreUtil.SEPARTER + temps[1];
				}
			}
		}

		if (str != null && !"".equals(str)) {
			String[] strs = str.split(StoreUtil.SEPARTER);
			int[] int_temp = new int[strs.length];
			for (int i = 0; i < strs.length; i++) {
				int_temp[i] = Integer.parseInt(strs[i]);
			}
			return int_temp;
		}
		return null;
	}

	/*** 返回当前选中行的下标值 没有选中返回-1 ***/
	public int getSelectionIndex() {
		if (getSelection().size() > 0) {
			return getInput().indexOf(getSelection().get(0));
		}
		return -1;
	}
}
